package com.codyy.felix.webconsole.plugins.route.core.utils;

import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author : issac
 * create at:  2019-04-19  11:32
 * @description: xml reader
 */
public class RouteXmlInfo {

    private static final String ROUTE_NAME_KEY = "route_name";
    private static final String ROUTE_DESC_KEY = "route_desc";

    private String fileUrl;

    private Document document;

    private String routeName;

    private String routeDesc;

    private String fromRoute;

    private List<String> desNames;

    public String getRouteName() {
        return routeName;
    }

    public String getRouteDesc() {
        return routeDesc;
    }

    public String getFromRoute() {
        return fromRoute;
    }

    public List<String> getDesNames() {
        return desNames;
    }

    public String getFileUrl() {
        return fileUrl;
    }

    public Document getDocument() {
        return document;
    }

    public RouteXmlInfo(String fileUrl) {
        this.fileUrl = fileUrl;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder dbBuilder;
        try {
            dbBuilder = dbf.newDocumentBuilder();
            this.document = dbBuilder.parse(fileUrl);
        } catch (Exception e) {
            throw new IllegalArgumentException("解析路由文件：" + fileUrl + "失败", e);
        }
    }

    public RouteXmlInfo(InputStream in) {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder dbBuilder;
        try {
            dbBuilder = dbf.newDocumentBuilder();
            this.document = dbBuilder.parse(in);
        } catch (Exception e) {
            throw new IllegalArgumentException("根据文件解析xml文件失败", e);
        }
    }

    /**
     * 路由名称和描述
     */
    public void setRouteNameAndDesc() {
        NodeList nList = document.getElementsByTagName("cm:property");
        for (int i = 0; i < nList.getLength(); i++) {
            NamedNodeMap map = nList.item(i).getAttributes();
            if(map == null || map.getLength() <= 0) {
                continue;
            }
            String routeName = Optional.ofNullable(map.getNamedItem("name")).map(Node::getNodeValue).orElse("");
            String routeDesc = Optional.ofNullable(map.getNamedItem("value")).map(Node::getNodeValue).orElse("");
            if (StringUtils.isNotBlank(routeDesc) || StringUtils.isNotBlank(routeName)) {
                this.routeName = routeName;
                this.routeDesc = routeDesc;
            }
        }
    }

    /**
     * 路由发送端和接收端
     */
    public void setRouteInfo() {
        NodeList nList = Optional.ofNullable(document.getElementsByTagName("route"))
                .map(o -> o.item(0))
                .map(Node::getChildNodes)
                .orElse(null);
        if (nList != null) {
            String fromNodeName = "";
            String fromRouteName = "";
            List<String> destNames = new ArrayList<>();
            for (int i = 0; i < nList.getLength(); i++) {
                fromNodeName = nList.item(i).getNodeName();
                switch (fromNodeName) {
                    case "from" :
                        fromRouteName = Optional.ofNullable(nList.item(i).getAttributes())
                                .map(o -> o.getNamedItem("uri"))
                                .map(Node::getNodeValue).orElse("");
                        break;
                    case "to" :
                        destNames.add(Optional.ofNullable(nList.item(i).getAttributes())
                                .map(o -> o.getNamedItem("uri"))
                                .map(Node::getNodeValue).orElse(""));
                        break;
                    default:
                        break;
                }
            }
            this.fromRoute = fromRouteName;
            this.desNames = destNames;
        }

    }

    @Override
    public String toString() {
        return "RouteXmlInfo{" +
                "fileUrl='" + fileUrl + '\'' +
                ", document=" + document +
                ", routeName='" + routeName + '\'' +
                ", routeDesc='" + routeDesc + '\'' +
                ", fromRoute='" + fromRoute + '\'' +
                ", desNames=" + desNames +
                '}';
    }

    public static void main(String[] args) {
        String file = "/Users/issac/resource/apache-servicemix-7.0.1/deploy/codyy-bundle-test001.xml";
        RouteXmlInfo rr = new RouteXmlInfo(file);
        rr.setRouteNameAndDesc();
        rr.setRouteInfo();
        System.out.println(rr.toString());
    }
}
